﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Grain.Crm.DataMigrator.CrmServices;
using Grain.Crm.DataMigrator.Imports;

namespace Grain.Crm.DataMigrator.Infrastructure
{
    [XmlInclude(typeof(SheetValueResolver)), XmlInclude(typeof(CrmIdResolver)), XmlInclude(typeof(ConstantValueResolver))]
    public class ImportEntityTask
    {
        protected ImportEntityTask()
        {
            EntityName = "";
            PrimaryKeyAppender = new ValueAppender(null, new ConstantValueResolver(null));
            SearchAttributes = new SearchAttribute[0];
            ValueAppenders = new ValueAppender[0];
            Container = new Container();
        }

        public ImportEntityTask(string entityName)
        {
            EntityName = entityName;
            PrimaryKeyAppender = new ValueAppender(null, new ConstantValueResolver(null));
            SearchAttributes = new SearchAttribute[0];
            ValueAppenders = new ValueAppender[0];
            Container = new Container();
        }

        public void Build(Builder builder)
        {
            builder.Build(this);
        }

        public virtual void Execute()
        {
            //1.get entity-data from sheet
            
            //2.check whether entity exists by query -> needed is query-search-attributes (for contact: 'fullname',etc)
            
            //var contactId = ImportsHelper.GetEntityId(service, thisEntityName, new string[] { "fullname" }, new string[] { ImportsGlobal.Contact });
            var contactId = ImportsHelper.GetEntityId(Service, EntityName, SearchAttributes);
            
            //2a.{if exists..}, add found entityId value to content: for contact: 'Contact' -> needed is primary key attribute name
            //set import mode only if it wasn't assign before
            if (contactId != null)
            {
                ImportMode = ImportMode.Update;

                var result = PrimaryKeyAppender.Append(HeaderRow, ContentRow);
                HeaderRow = result.Key;
                ContentRow = result.Value;
            }
            else
                ImportMode = ImportMode.CreateNew;

            //3.add reference data, -> needed is referenced entities -> lookup display names

            foreach(var appender in ValueAppenders)
            {
                var result = appender.Append(HeaderRow, ContentRow);
                HeaderRow = result.Key;
                ContentRow = result.Value;
            }

            //4.update globals

        }
       

        public string EntityName { get; set; }
        public SearchAttribute[] SearchAttributes { get; set; }
        public ValueAppender PrimaryKeyAppender { get; set; }
        public ValueAppender[] ValueAppenders { get; set; }
        public ImportMode ImportMode { get; set; }
        
        [XmlIgnore]
        public string HeaderRow { get; set; }
        [XmlIgnore]
        public string ContentRow { get; set; }
        [XmlIgnore]
        public Container Container { get; set; }
        [XmlIgnore]
        public Container SharedContainer { get; set; }
        [XmlIgnore]
        public ICrmService Service { get; set; }
    }

    public enum ImportMode { Unassigned, CreateNew, Update, }
    
}
